package com.starsoft.smdc.crawler.xueqiu;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.fasterxml.jackson.databind.JsonNode;
import com.starsoft.frame.fileimport.CsvReader;
import com.starsoft.frame.fileimport.pojo.Column;
import com.starsoft.frame.fileimport.pojo.DataTable;
import com.starsoft.frame.fileimport.pojo.NullType;
import com.starsoft.frame.fileimport.pojo.Table;
import com.starsoft.frame.fileimport.pojo.Table.TitleType;
import com.starsoft.frame.fileimport.pojo.ValueType;
import com.starsoft.frame.util.DateUtil;
import com.starsoft.frame.util.MapUtil;
import com.starsoft.smdc.bean.SmdcMarketDaily;
import com.starsoft.smdc.bean.SmdcMarketDailyId;
import com.starsoft.smdc.bean.SmdcSecurity;
import com.starsoft.smdc.crawler.common.MarketDailyCrawler;
import com.starsoft.smdc.service.HolidayService;
import com.starsoft.smdc.util.SecurityType;

public class MarketDailyV5Xueqiu extends XueqiuService implements MarketDailyCrawler {

	private static Logger logger = LoggerFactory.getLogger(MarketDailyV5Xueqiu.class);

	@Override
	public List<SmdcMarketDaily> update(SmdcSecurity security, Date begin) {
		return update(Arrays.asList(security), Arrays.asList(begin));
	}

	@Override
	public List<SmdcMarketDaily> update(List<SmdcSecurity> securityList, List<Date> begin) {
		Date end = new Date();
		if(holidayService.isBeforeClose(end)){
			end = holidayService.getNextBusinessDay(end, -1);
		} else {
			end = holidayService.getBusinessDay(end, true);
		}
		
		List<SmdcMarketDaily> result = new ArrayList<SmdcMarketDaily>();
		for (int i = 0; i < securityList.size(); i++) {
			SmdcSecurity security = securityList.get(i);
			if("of".equals(security.getExchange())) continue;
			try {
				List<SmdcMarketDaily> markets = getMarket(security, begin.get(i), end);
				result.addAll(markets);
				marketDailyDao.saveOrUpdateBatch(markets);
			} catch (Exception e) {
				logger.error("", e);
			}
		}
		return result;
	}

	private List<SmdcMarketDaily> getMarket(SmdcSecurity security, Date begin, Date end) throws ParseException {
		List<SmdcMarketDaily> marketList = new ArrayList<SmdcMarketDaily>();
		long count = DateUtil.getDays(begin, end)+2;
		if(count<=0) {
			return marketList;
		}
		String secId = convertSecId(security.getSecId(), false);

		String apiName = "marketV5";
		String[] params = { secId, String.valueOf(end.getTime()), String.valueOf(count) };
		String response = this.request(apiName, params);
		if(response==null||response.length()<60) {
			logger.info("获取行情失败："+security.getSecName());
			return marketList;
		}
		String content = getContent(response);

		List<Column> columnList = new ArrayList<Column>();
		columnList.add(new Column(0, "tradeDate", ValueType.DateTime, NullType.notnull, "timestamp"));
		columnList.add(new Column(1, "turnoverVol", ValueType.Double, NullType.nullable));
		columnList.add(new Column(2, "openPrice", ValueType.Double, NullType.nullable));
		columnList.add(new Column(3, "highPrice", ValueType.Double, NullType.nullable));
		columnList.add(new Column(4, "lowPrice", ValueType.Double, NullType.nullable));
		columnList.add(new Column(5, "closePrice", ValueType.Double, NullType.notnull));
		columnList.add(new Column(6, "priceChange", ValueType.Double, NullType.nullable));
		columnList.add(new Column(7, "percent", ValueType.Double, NullType.notnull));
		columnList.add(new Column(8, "turnoverRate", ValueType.Double, NullType.nullable));
		Table table = new Table(TitleType.Null, columnList);

		CsvReader reader = new CsvReader();
		DataTable dataTable = reader.read(content, table);
		if(dataTable == null){
			return marketList;
		}
		
		for (Map<String, Object> mapObject : dataTable.getData()) {
			Date tradeDate = (Date) mapObject.get("tradeDate");
			if(tradeDate.before(begin)){
				continue;
			}
			SmdcMarketDailyId id = new SmdcMarketDailyId(security.getSecId(), tradeDate);
			SmdcMarketDaily marketDaily = marketDailyDao.get(id);
			if (marketDaily == null) {
				marketDaily = new SmdcMarketDaily(id);
			}
			MapUtil.updateBean(marketDaily, mapObject);
			if (marketDaily.getTurnoverVol() != null && marketDaily.getTurnoverVol() == 0) {
				marketDaily.setIsOpen(false);
			} else {
				marketDaily.setIsOpen(true);
			}
			double preClose = marketDaily.getClosePrice() - marketDaily.getPriceChange();
			marketDaily.setPreClosePrice(preClose);
			marketDaily.setPercent(marketDaily.getPercent()/100);
			if(SecurityType.isIndex(security.getSecType())){
				marketDaily.setTurnoverValue(marketDaily.getTurnoverVol());
			} else {
				marketDaily.setTurnoverValue(marketDaily.getTurnoverVol()*marketDaily.getClosePrice());
			}
			marketList.add(marketDaily);
		}
		return marketList;
	}
	
	private String getContent(String response){
		JsonNode responseJson = getJsonNode(response);
		JsonNode chartlist = responseJson.get("data").get("item");
		String content = chartlist.toString();
		content = content.replaceAll("\\],\\[", "\n");
		content = content.replaceAll("\\]", "").replaceAll("\\[", "");
		return content;
	}

}
